#pragma once 
#include <iostream>
#include <string>
#include <unordered_map>
#include"Socket.hpp"
#include"Epoller.hpp"
#include"Connection.hpp"

using namespace EpollerModule;
#define EPOLL_BLOCK -1



//管理一堆Connection，就是Reactor
class TcpServer
{
public:
    static const int gmaxevents=64;
    TcpServer():_isrunning(false),_timeout(EPOLL_BLOCK)
    {
        _epoll.initEpoller();
    }
    bool IsConnectionExists(int sockfd)
    {
        auto iter=_connections.find(sockfd);
         if (iter == _connections.end())
            return false;
        else
            return true;
    }
    void AddConnection(Connection *conn)
    {
        if(!conn)
        return;
        if(IsConnectionExists(conn->SockFd()))
        return;
        _connections.insert(std::make_pair(conn->SockFd(),conn));
        lg.LogMessage(Info, "add a new connection success, sockfd: %d\n", conn->SockFd());
        //epoll进行管理
        _epoll.AddEvent(conn->SockFd(),conn->Events());
    }

    void EnableReadWrite(int sockfd,bool readable,bool writeable)
    {
        if(!IsConnectionExists(sockfd))
        return;
        uint32_t events=((readable?EPOLLIN:0)|(writeable?EPOLLOUT:0)|EPOLLET);
        _connections[sockfd]->SetEvents(events);

        //修改epoll，写入内核
        _epoll.ModEvent(sockfd,_connections[sockfd]->Events());
    }
    void RemoveConnection(int sockfd)
    {
        if (!IsConnectionExists(sockfd))
            return;
        _connections[sockfd]->SetEvents(0);
        //清理epoll关心
        _epoll.DelEvent(sockfd);

        _connections.erase(sockfd);
    }
    void LoopOnce(int timeout)
    {
        std::cout<<"开始事件派发\n";
        int n=_epoll.Wait(_revs,gmaxevents,timeout);
        std::cout<<"监控到"<<n<<"个事件\n";
        for(int i=0;i<n;i++)
        {
            int sockfd=_revs[i].data.fd;
            uint32_t events=_revs[i].events;
            if((events&EPOLLERR))
            events|=(EPOLLIN | EPOLLOUT);
            if(events&EPOLLHUP)
            events|=(EPOLLIN | EPOLLOUT);
            // 未来所有的IO操作，都会转化成为下面的部分
            // 整个代码有没有执行IO代码？没有！
            // IO代码将来在哪里？？？connection的回调中.
            // 我们在干什么？？？事件派发
            if((events&EPOLLIN)&&IsConnectionExists(sockfd))
            {
                std::cout<<"读事件 即将处理\n";
                if(_connections[sockfd]->_recver)
                {
                    std::cout<<sockfd<<"处理\n";
                    _connections[sockfd]->_recver(_connections[sockfd]);
                }
            }
             if((events&EPOLLOUT)&&IsConnectionExists(sockfd))
            {
                std::cout<<"写事件\n";
                if(_connections[sockfd]->_sender)
                _connections[sockfd]->_sender(_connections[sockfd]);
            }
        }
        std::cout<<"事件分发完毕 \n";
    }

    void Dispatcher()
    {
        _isrunning=true;
        while(_isrunning)
        {
            _epoll.DebugFdList();
            LoopOnce(_timeout);//事件派发
        }
        _isrunning=false;
    }

    ~TcpServer()
    {
        
    }

private:
    Epoller _epoll;
    struct epoll_event _revs[gmaxevents];
    int _timeout;
    std::unordered_map<int,Connection*> _connections;
    bool _isrunning;

};
